#ifndef YCCORELIVEINFO_H
#define YCCORELIVEINFO_H

#include "modeltype.h"
#include <QJsonDocument>
#include <QJsonObject>

namespace yc {

struct StreamPullUrl
{
    QString full_hd1;
    QString hd1;
    QString sd1;
    QString sd2;

    StreamPullUrl() = default;
    StreamPullUrl& operator=(const QJsonObject& jo)
    {
        full_hd1 = jo["FULL_HD1"].toString();
        hd1 = jo["HD1"].toString();
        sd1 = jo["SD1"].toString();
        sd2 = jo["SD2"].toString();
        return *this;
    }

    bool isValid() const
    {
        return !full_hd1.isEmpty() || !hd1.isEmpty() || !sd1.isEmpty() || !sd2.isEmpty();
    }

    QJsonObject toJsonObject() const
    {
        QJsonObject jo { { "FULL_HD1", full_hd1 }, { "HD1", hd1 }, { "SD1", sd1 }, { "SD2", sd2 } };
        return jo;
    }
};

struct StreamExtra
{
    int width;
    int height;

    StreamExtra() : width(0), height(0) { }
    StreamExtra& operator=(const QJsonObject& jo)
    {
        width = jo["width"].toInt();
        height = jo["height"].toInt();
        return *this;
    }
    QJsonObject toJsonObject() const
    {
        QJsonObject jo { { "width", width }, { "height", width } };
        return jo;
    }
};

struct StreamUrl
{
    StreamPullUrl flv_pull_url;
    StreamPullUrl hls_pull_url_map;
    QString hls_pull_url;
    QString default_resolution;
    StreamExtra extra;

    StreamUrl() = default;
    explicit StreamUrl(const QJsonObject& jo) { this->operator=(jo); }

    bool isValid() const
    {
        return flv_pull_url.isValid() || hls_pull_url_map.isValid() || !hls_pull_url.isEmpty();
    }

    StreamUrl& operator=(const QJsonObject& jo)
    {
        flv_pull_url = jo["flvPullUrl"].toObject();
        hls_pull_url_map = jo["hlsPullUrlMap"].toObject();
        hls_pull_url = jo["hlsPullUrl"].toString();
        default_resolution = jo["defaultResolution"].toString();
        extra = jo["extra"].toObject();
        return *this;
    }

    QJsonObject toJsonObject() const
    {
        return QJsonObject { { "flvPullUrl", flv_pull_url.toJsonObject() },
                             { "hlsPullUrlMap", hls_pull_url_map.toJsonObject() },
                             { "hlsPullUrl", hls_pull_url },
                             { "defaultResolution", default_resolution },
                             { "extra", extra.toJsonObject() } };
    }

    QString toJson() const { return QJsonDocument(toJsonObject()).toJson(QJsonDocument::Compact); }
    static StreamUrl fromJson(const QString& json)
    {
        return StreamUrl { QJsonDocument::fromJson(json.toUtf8()).object() };
    }
};

struct LiveInfo
{
    int id;
    QString platform_id;
    QString platform_web_rid;
    int owner;
    int presenter;
    int total_user_count;
    int user_count;
    int view_count;
    int like_count;
    StreamUrl stream_url;
    StreamUrl web_stream_url;
    QString title;
    QString qrcode_url;
    int status;
    QDateTime update_time;
    int updater;

    LiveInfo& operator=(const QJsonObject& jo)
    {
        id = jo["id"].toInt();
        platform_id = jo["platformId"].toString();
        platform_web_rid = jo["platformWebRid"].toString();
        owner = jo["owner"].toInt();
        presenter = jo["presenter"].toInt();
        total_user_count = jo["totalUserCount"].toInt();
        user_count = jo["userCount"].toInt();
        view_count = jo["viewCount"].toInt();
        like_count = jo["likeCount"].toInt();
        stream_url = jo["streamUrl"].toObject();
        web_stream_url = jo["webStreamUrl"].toObject();
        title = jo["title"].toString();
        qrcode_url = jo["qrcodeUrl"].toString();
        status = jo["status"].toInt(LiveStatus::INACTIVE_LIVE_STATUS);
        update_time = QDateTime::fromString(jo["updateTime"].toString(), Qt::ISODate);
        if (!update_time.isValid()) {
            update_time = QDateTime::currentDateTime();
        }
        updater = jo["updater"].toInt();
        return *this;
    }

    static LiveInfo fromJsonObject(const QJsonObject& jo)
    {
        return LiveInfo { jo["id"].toInt(),
                          jo["platformId"].toString(),
                          jo["platformWebRid"].toString(),
                          jo["owner"].toInt(),
                          jo["presenter"].toInt(),
                          jo["totalUserCount"].toInt(),
                          jo["userCount"].toInt(),
                          jo["viewCount"].toInt(),
                          jo["likeCount"].toInt(),
                          StreamUrl { jo["streamUrl"].toObject() },
                          StreamUrl { jo["webStreamUrl"].toObject() },
                          jo["title"].toString(),
                          jo["qrcodeUrl"].toString(),
                          jo["status"].toInt(yc::LiveStatus::INACTIVE_LIVE_STATUS),
                          QDateTime::fromString(jo["updateTime"].toString(), Qt::ISODate),
                          jo["updater"].toInt() };
    }
};

} // namespace yc

#endif // YCCORELIVEINFO_H
